package com.xh.bussiness.system.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.xh.bussiness.permission.model.User;
import com.xh.bussiness.system.bean.request.AuditApplyRequest;
import com.xh.bussiness.system.constant.AuditApplyConstant;
import com.xh.bussiness.system.model.AuditApply;
import com.xh.bussiness.system.dao.AuditApplyMapper;
import com.xh.bussiness.system.model.AuditApplyLog;
import com.xh.bussiness.system.service.IAuditApplyLogService;
import com.xh.bussiness.system.service.IAuditApplyService;
import com.xh.core.service.impl.BaseServiceImpl;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import com.xh.core.bean.XhPage;

import java.util.Date;
import java.util.List;

/**
 * <p>
 *  服务实现类
 * </p>
 *
 * @author daiwei
 * @since 2018-11-20
 */
@Service
public class AuditApplyServiceImpl extends BaseServiceImpl<AuditApplyMapper, AuditApply> implements IAuditApplyService {

    @Autowired
    private IAuditApplyLogService auditApplyLogService;

    @Override
    public XhPage queryAuditApplyPage(XhPage page, AuditApplyRequest bean) {
        QueryWrapper qw=new QueryWrapper<AuditApply>();
        //拼装条件
        qw=prepareParams(bean, qw);

        return (XhPage) this.dao.selectPage(page,qw);
    }

    @Override
    public List queryAuditApply(AuditApplyRequest bean) {
        QueryWrapper qw=new QueryWrapper<AuditApply>();
        //拼装条件
        qw=prepareParams(bean, qw);

        return this.dao.selectList(qw);
    }


    /**
     * 准备条件
     * @param bean
     * @param qw
     */
    private QueryWrapper prepareParams(AuditApplyRequest bean, QueryWrapper qw) {
        if(bean.getIds()!=null&&bean.getIds().length>0){
            qw.in("id",bean.getIds());
        }
        return qw;
    }

    /**
     *
     * <p>作者:David</p>
     * <p>功能描述:创建新的申请流程</p>
     * <p>创建时间:20122012-8-3下午02:45:19</p>
     * <p>@param entityMetavalue 实体类别：常量AuditApplyConstant.EntityMetavalue
     * <p>@param entryId 实体ID
     * <p>@param maxAuditLevel 最大审核级别（标识审核层级）
     * <p>@param applier 申请人对象
     * <p>@return</p>
     * <p>修改:</p>
     */
    private AuditApply createNewAuditApply(Integer entityMetavalue,
                                                 String entryId, Integer maxAuditLevel, User applier) {
        AuditApply bean=new AuditApply();
        bean.setEntityMeta(entityMetavalue);
        bean.setEntityId(entryId);
        bean.setFinalStatus(AuditApplyConstant.FinalStatus.UN_AUDIT);
        bean.setPreAuditStatus(AuditApplyConstant.AuditStatus.UN_SUBMIT);
        bean.setAuditStatus(AuditApplyConstant.AuditStatus.UN_SUBMIT);
        bean.setSubmitTo(1);
        bean.setAuditLevel(0);
        bean.setPreAuditLevel(0);
        bean.setMaxAuditLevel(maxAuditLevel);
        bean.setAuditCount(0);
        this.insert(bean);
        return bean;
    }

    /**
     *
     * <p>作者:David</p>
     * <p>功能描述:取消审核</p>
     * <p>创建时间:20122012-8-3下午03:12:12</p>
     * <p>@param canceler 撤销对象
     * <p>@param auditLevel 撤销级别
     * <p>@param remark 备注信息
     * <p>@return 审核日志对象</p>
     * <p>修改:</p>
     */
    private AuditApplyLog cancelAuditApply(String auditApplyId,User canceler, String remark){
        AuditApply bean =this.getById(auditApplyId);
        bean.setPreAuditStatus(bean.getAuditStatus());
        bean.setAuditStatus(AuditApplyConstant.AuditStatus.CANCLED);
        //TODO 上一次操作级别为当前等级
        bean.setPreAuditLevel(bean.getAuditLevel());
        //TODO 一级待审核
        //this.auditLevel=0;
        bean.setAuditLevel(0);
        bean.setSubmiterId(canceler.getId());
        bean.setSubmiterName(canceler.getUsername());
        bean.setSubmitTime(new Date());
        this.update(bean);
        AuditApplyLog log= AuditApplyLog.createCancelLog(bean.getId(), remark,bean.getPreAuditLevel());
        auditApplyLogService.insert(log);
        return log;
    }

    /**
     *
     * <p>作者:David</p>
     * <p>功能描述:提交审核申请</p>
     * <p>创建时间:20122012-8-3下午03:12:12</p>
     * <p>@param submiter 提交人对象
     * <p>@param remark 备注信息
     * <p>@return 审核日志对象</p>
     * <p>修改:</p>
     */
    public AuditApplyLog submitAuditApply(String auditApplyId,User submiter,String remark){
        AuditApply bean =this.getById(auditApplyId);
        bean.setAuditStatus(AuditApplyConstant.AuditStatus.SUBMITED);
        bean.setPreAuditStatus(AuditApplyConstant.AuditStatus.UN_SUBMIT);
        //TODO 上一次操作级别为当前等级
        bean.setPreAuditLevel(bean.getAuditLevel());
        //TODO 一级待审核
        bean.setAuditLevel(bean.getSubmitTo());
        bean.setSubmiterId(submiter.getId());
        bean.setSubmiterName(submiter.getUsername());
        bean.setSubmitTime(new Date());
        this.update(bean);

        AuditApplyLog log= AuditApplyLog.createSubmitLog(bean.getId(), remark,bean.getPreAuditLevel());
        auditApplyLogService.insert(log);
        return log;
    }
    /**
     *
     * <p>作者:David</p>
     * <p>功能描述:提交审核申请</p>
     * <p>创建时间:20122012-8-3下午03:12:12</p>
     * <p>@param submiter 提交人对象
     * <p>@param toLevel 提交到的级别
     * <p>@param remark 备注信息
     * <p>@return 审核日志对象</p>
     * <p>修改:</p>
     */
    public AuditApplyLog submitAuditApply(String auditApplyId,User submiter,Integer toLevel,String remark){
        AuditApply bean =this.getById(auditApplyId);
        if(toLevel==null||toLevel<=bean.getAuditLevel()){
            return this.submitAuditApply(auditApplyId,submiter, remark);
        }
        bean.setPreAuditStatus(bean.getAuditStatus());
        bean.setAuditStatus(AuditApplyConstant.AuditStatus.SUBMITED);
        //TODO 上一次操作级别为当前等级
        bean.setPreAuditLevel(bean.getAuditLevel());
        //TODO 一级待审核
        bean.setSubmitTo(toLevel);
        bean.setAuditLevel(toLevel);
        bean.setSubmiterId(submiter.getId());
        bean.setSubmiterName(submiter.getUsername());
        bean.setSubmitTime(new Date());
        this.update(bean);
        AuditApplyLog log= AuditApplyLog.createSubmitLog(bean.getId(), remark,bean.getPreAuditLevel());
        auditApplyLogService.insert(log);
        return log;
    }

    /**
     *
     * <p>作者:David</p>
     * <p>功能描述:审核通过操作</p>
     * <p>创建时间:20122012-8-3下午03:22:07</p>
     * <p>@param auditer
     * <p>@param remark
     * <p>@return</p>
     * <p>修改:</p>
     */
    public AuditApplyLog passAuditApply(String auditApplyId,User auditer,String remark){
        AuditApply bean =this.getById(auditApplyId);
        return passAuditApply(auditApplyId,auditer,bean.getSubmitTo()+1,remark);
    }

    /**
     *
     * <p>作者:David</p>
     * <p>功能描述:审核通过操作</p>
     * <p>创建时间:20122012-8-3下午03:22:07</p>
     * <p>@param auditer
     * <p>@param toLevel 审核进入到哪一级
     * <p>@param remark
     * <p>@return</p>
     * <p>修改:</p>
     */
    public AuditApplyLog passAuditApply(String auditApplyId,User auditer,Integer toLevel,String remark){
        AuditApply bean =this.getById(auditApplyId);
        bean.setPreAuditStatus(AuditApplyConstant.AuditStatus.PASSED);
        //TODO 上一次操作级别为当前等级
        bean.setPreAuditLevel(bean.getAuditLevel());
        if(bean.getAuditLevel().intValue()==bean.getMaxAuditLevel().intValue()){//如果已到最大级别，则终审
            bean.setFinalStatus(AuditApplyConstant.FinalStatus.FINISHED);
            bean.setAuditStatus(AuditApplyConstant.AuditStatus.PASSED);
        }else{
            bean.setFinalStatus(AuditApplyConstant.FinalStatus.AUDITED);//否则标识为已审
            bean.setAuditStatus(AuditApplyConstant.AuditStatus.SUBMITED);
            bean.setSubmitTo(toLevel);//指向下一级别:当前审核级别+1
            bean.setAuditLevel(bean.getSubmitTo());

        }
        bean.setAuditerId(auditer.getId());
        bean.setAuditerName(auditer.getUsername());
        bean.setAuditTime(new Date());
        this.update(bean);

        AuditApplyLog log=AuditApplyLog.createPassLog(bean.getId(), remark,bean.getPreAuditLevel());
        auditApplyLogService.insert(log);
        return log;
    }

    /**
     *
     * <p>作者:David</p>
     * <p>功能描述:审核驳回操作</p>
     * <p>创建时间:20122012-8-3下午03:41:37</p>
     * <p>@param auditer 审核人
     * <p>@param remark 备注
     * <p>@param rejectTo 驳回位置（可为null，此时驳回给提交人）
     * <p>@param isReAllAudit 驳回后重新提交后是否需要重走整个审核流程（为null或false则不走，重新提交后会直接至当前节点）
     * <p>@param isFinal 是否终审（null和false为非终审）
     * <p>@return</p>
     * <p>修改:</p>
     */
    public AuditApplyLog rejectAuditApply(String auditApplyId,User auditer, String remark,
                                          Integer rejectTo, Boolean isReAllAudit, Boolean isFinal) {
        AuditApply bean =this.getById(auditApplyId);
        //TODO 上一次操作级别为当前等级
        bean.setPreAuditLevel(bean.getAuditLevel());
        if(isReAllAudit!=null&&isReAllAudit){//如果设置为重走整个流程，则submitTo设为1
            bean.setSubmitTo(1);
        }else{
            bean.setSubmitTo(bean.getAuditLevel());//否则再次提交后回到当前流程位置
        }

        if(rejectTo==null){
            bean.setAuditLevel(0);//返回给提交人
        }else{
            bean.setAuditLevel(rejectTo);
        }
        if(isFinal!=null&&isFinal){//是终审
            bean.setFinalStatus(AuditApplyConstant.FinalStatus.FINISHED);//标识为终审
            bean.setAuditStatus(AuditApplyConstant.AuditStatus.REJECTED);
            bean.setPreAuditStatus(AuditApplyConstant.AuditStatus.REJECTED);
        }else{
            bean.setFinalStatus(AuditApplyConstant.FinalStatus.AUDITED);//标识为终审
            bean.setAuditStatus(AuditApplyConstant.AuditStatus.UN_SUBMIT);
            bean.setPreAuditStatus(AuditApplyConstant.AuditStatus.REJECTED);
        }

        bean.setAuditerId(auditer.getId());
        bean.setAuditerName(auditer.getUsername());
        bean.setAuditTime(new Date());
        this.update(bean);

        AuditApplyLog log= AuditApplyLog.createRejectLog(bean.getId(), remark,bean.getPreAuditLevel());
        auditApplyLogService.insert(log);
        return log;
    }
}
